/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: hubnsHdr.h,v 1.1 2008-03-30 00:55:36 amaula Exp $
 *
 */
#ifndef _HUBNSHDR_H_
#define _HUBNSHDR_H_

#include <inttypes.h>
#include "protocolID.h"

// Protocol identification
#define HUBNSPROTOCOL_NUMBER                   0x02

// Network request types and parameters
/**
 * Query a name from the Hub. The 'name' field of the structure
 * should contain the name to be queried.
 * 
 * Reply to this request is marked with FLAG_REPLY, and
 * on success, the FLAG_ERROR is NOT Set. If the request
 * succeeded, the ID is stored in the 'id' fields.
 */
#define HUBNS_REQUEST_QUERYNAME                0x01


/**
 * Register a 'name' to 'ID'. If the ID is left zero, the 
 * originating connection is registered (NOTE: This may change in
 * the future - you may not be able to register foreign ID:s)
 * If the 'value' field is non-zero, it is used as maximum_age of
 * the entry. (The entry is removed from the name cache after
 * the maximum_age number of _seconds_ is elapsed without 
 * entry refreshes)
 *
 * NOTE: Please use the form _REGISTER. The REGISTERNAME is
 * obsolete and deprecated.
 *
 * Reply to this message is identical to sent, except that
 * 'flags' field will contain FLAG_REPLY and no FLAG_ERROR on
 * success.
 */
#define HUBNS_REQUEST_REGISTERNAME             0x02
#define HUBNS_REQUEST_REGISTER             0x02


/**
 * Request reverse name query (name by id)
 *
 * Reply contains the 'name' bound to requested id (on success)
 * 'flags' field will contain FLAG_REPLY and no FLAG_ERROR on
 * success.
 */
#define HUBNS_REQUEST_REVERSEQUERYNAME         0x03


/**
 * Unregister an name. Specify the name to 'unregister' in the 
 * 'name' field.
 *
 * 'flags' field will contain FLAG_REPLY and no FLAG_ERROR on
 * success.
 */
#define HUBNS_REQUEST_UNREGISTERNAME           0x04


/**
 * Lists all registered names on the HubNS module. This has a special format,
 * which contains extra payload after the hubns header. Description follows:
 * - 'value' field in the main header specified the count of
 *   following THubNSProtocolNameEntry entries. Each entry contains
 *   information concerning one registered entry.
 *
 * 'flags' field will contain FLAG_REPLY and no FLAG_ERROR on
 * success.
 */
#define HUBNS_REQUEST_LISTREGISTEREDNAMES      0x05


/**
 * FIXME: Unimplemented
 * This request only refreshes the existing HubNS entry. This matters
 * when maximum age is set for the particular entry.
 *
 */
#define HUBNS_REQUEST_REFRESHNAME              0x06


/// Current minimum limit for request number
#define HUBNS_REQUEST_MIN                      0x01

/// Current maximum limit for request number
#define HUBNS_REQUEST_MAX                      0x05

/////////////////////// Flags /////////////////////////////////////////////////
#define HUBNS_FLAG_NONE                        0x00
#define HUBNS_FLAG_REPLY                       PROTOCOL_FLAGBIT(0)
#define HUBNS_FLAG_ERROR                       PROTOCOL_FLAGBIT(1)
#define HUBNS_FLAG_FORCEREGISTER               PROTOCOL_FLAGBIT(2)
#define HUBNS_FLAG_IGNOREMASTER                PROTOCOL_FLAGBIT(3)
#define HUBNS_FLAG_NEEDREASSIGN                PROTOCOL_FLAGBIT(4)
#define HUBNS_FLAG_HUB2HUB                     PROTOCOL_FLAGBIT(5)

// Limits and constants specific to this module
#define HUBNS_NAME_MAX                         32

// Redefines
#define HUBNS_TARGET_LOCAL                     CONNECTIONLIST_TARGETID_LOCAL
#define HUBNS_SOURCE_LOCAL                     CONNECTIONLIST_SOURCEID_LOCAL

typedef struct _hubnsNameEntry
{
  unsigned int id;              ///< ID registered
  int flags;                    ///< Flags (Currently none defined)
  char name[HUBNS_NAME_MAX];    ///< Name (always \0 terminated string)
  int age_left;                 ///< Timeout in seconds
} THubNSProtocolNameEntry;

typedef struct _hubnsProtocolHeader
{
  TProtocolIdentification protocol_id;

  uint32_t target_id;           ///< Target ID (where this packet is going)
  uint32_t source_id;           ///< Source ID (where this packet is coming from)

  uint16_t request;             ///< Type of request
  uint16_t flags;               ///< Flags

  int32_t identifier;           ///< Message identifier
  int32_t value;                ///< Generic 32 bit value

  union {
    struct {
      uint16_t client_id;       ///< For backwards compability
      uint16_t hub_id;          ///< For backwards compability
    };
    uint32_t requested_id;        ///< Id requested
  };

  uint32_t requester_id;        ///< Id of requester
  
  char name[HUBNS_NAME_MAX];    ///< Name to query/register ('\0' terminated)
  char reserved[sizeof(int) * 4]; ///< Reserved, dont use.
} THubNSProtocolHeader;

#define SIZEOF_THUBNSPROTOCOLHEADER (4+4+4+2+2+4+4+4+4+16+HUBNS_NAME_MAX)


#endif
